﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using RbacPermissionManage.Application.Admins.Dto;
using RbacPermissionManage.Common;
using RbacPermissionManage.DoMain;
using RbacPermissionManage.Repository;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Formats.Asn1;
using System.Security.Principal;
using System.Security.Claims;

namespace RbacPermissionManage.Application.Admins
{
    public class AdminServices : IAdminServices
    {
        private readonly IRepository<Admin>repository;
        private readonly IMapper mapper;
        private readonly IHttpContextAccessor httpContext;

        public AdminServices(IRepository<Admin> repository, IMapper mapper,IHttpContextAccessor httpContext)
        {
            this.repository = repository;
            this.mapper = mapper;
            this.httpContext = httpContext;
        }

        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="registerDto"></param>
        /// <returns></returns>
        public async Task<ResultDto> RegisterAsync(RegisterDto registerDto)
        {
            //查用户名
            var admin = await repository.FirstOrDefaultAsync(x => x.UserName == registerDto.UserName);
            if (admin != null)
            {
                return new ResultDto { Code = Code.Failed, Message = "用户名已使用" };
            }

            //MD5加密
            //registerDto.Pwd.Md5();

            //添加数据
            Admin adminInfo = new Admin
            {
                UserName = registerDto.UserName,
                Pwd = registerDto.Pwd.Md5(),//Md5加密
                CreateName = "张三",
                CreateTime = DateTime.Now,
            };

            try
            {
                await repository.InsertAsync(adminInfo);//调仓储的添加方法
                return new ResultDto { Code = Code.Success };
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Code.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 添加管理员
        /// </summary>
        /// <param name="createDto"></param>
        /// <returns></returns>
        public async Task<ResultDto> CreateAsync(AdminCreateDto createDto)
        {
            //查用户名
            var isExists = await repository.FirstOrDefaultAsync(x => x.UserName == createDto.UserName);
            if (isExists != null)
            {
                return new ResultDto { Code = Code.Failed, Message = "用户名已使用" };
            }

            Admin admin = mapper.Map<AdminCreateDto, Admin>(createDto);
            admin.Pwd = admin.Pwd.Md5();
            //var user = httpContext.HttpContext.User;
            //var claims = httpContext.HttpContext.User.Claims;
            //admin.CreateName = httpContext.HttpContext.User.Identity.Name;
            //admin.CreateTime = DateTime.Now;


            try
            {
                await repository.InsertAsync(admin);//调仓储的添加方法
                return new ResultDto { Code = Code.Success };
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Code.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 根据Id获取adminDto
        /// </summary>
        /// <param name="AdminId">管理员Id</param>
        /// <returns></returns>
        public async Task<ResultDto<AdminListDto>> BackfillAsync(int AdminId)
        {
            var admin = await repository.FindAsync(AdminId);
            return new ResultDto<AdminListDto> { Code = Code.Success, Data = mapper.Map<Admin, AdminListDto>(admin) };
        }

        /// <summary>
        /// 修改管理员
        /// </summary>
        /// <param name="updateDto"></param>
        /// <returns></returns>
        public async Task<ResultDto> UpdateAsync(AdminUpdateDto updateDto)
        {
            //查用户名
            var isExists = await repository.FirstOrDefaultAsync(x => x.UserName == updateDto.UserName && x.AdminId!=updateDto.AdminId);
            if (isExists != null)
            {
                return new ResultDto { Code = Code.Failed, Message = "用户名已使用" };
            }
            Admin entity = await repository.FindAsync(updateDto.AdminId);
            Admin admin = mapper.Map(updateDto,entity);
            admin.UpdateName = httpContext.HttpContext.User.Identity.Name;
            admin.UpdateTime = DateTime.Now;


            try
            {
                await repository.UpdateAsync(entity);//调仓储的添加方法
                return new ResultDto { Code = Code.Success };
            }
            catch (Exception e)
            {
                return new ResultDto { Code = Code.Failed, Message = e.Message };
            }
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="loginDto"></param>
        /// <returns></returns>
        public async Task<LoginResultDto> LoginAsync(LoginDto loginDto)
        {
            //判断用户名是否正确
            var admin = await repository.FirstOrDefaultAsync(x => x.UserName == loginDto.UserName);
            if(admin == null)
            {
                return new LoginResultDto { Code=LoginEnum.NoAccount,Message="用户名不正确"};
            }
            else
            {
                //判断密码是否正确
                if (admin.Pwd != loginDto.Pwd.Md5())
                {
                    return new LoginResultDto { Code = LoginEnum.PasswordError, Message="密码错误"};
                }
                else
                {
                    Admin entity = await repository.FindAsync(admin.AdminId);
                    entity.LastLoginIP = httpContext.HttpContext.Connection.RemoteIpAddress.ToString();//末次登录IP
                    entity.LastLoginTime = DateTime.Now;//末次登录时间
                    await repository.SaveChangesAsync();
                    //await repository.UpdateAsync(entity);

                    return new LoginResultDto { Code = LoginEnum.Success };
                }
            }
        }

        /// <summary>
        /// 查询分页显示管理员列表
        /// </summary>
        /// <param name="searchDto"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<ResultDto<(int,List<AdminListDto>)>> GetAdminAsync(AdminSearchDto searchDto,int pageIndex,int pageSize)
        {
            try
            {
                var list = repository.Queryable().Where(x => x.IsDel == false);
                if (!string.IsNullOrEmpty(searchDto.Keywords))
                {
                    list = list.Where(x => x.UserName.Contains(searchDto.Keywords) || x.Email.Contains(searchDto.Keywords));
                }
                if (searchDto.StartTime != null)
                {
                    list=list.Where(x=>x.CreateTime>=searchDto.StartTime.Value.AddDays(1));
                }
                if(searchDto.EndTime!= null)
                {
                    list=list.Where(x=>x.CreateTime<searchDto.EndTime.Value.AddDays(2));
                }
                var PageData = await list.OrderByDescending(x=>x.CreateTime).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
                var result = mapper.Map<List<Admin>, List<AdminListDto>>(PageData);

                //var result = mapper.Map<List<Admin>, List<AdminListDto>>(list);
                return new ResultDto<(int,List<AdminListDto>)> { Data=(await list.CountAsync(),result) };
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="AdminId"></param>
        /// <returns></returns>
        public async Task<ResultDto<bool>> DeleteAsync(int AdminId)
        {
            try
            {
                await repository.DeleteAsync(AdminId);
                return new ResultDto<bool> { Code = Code.Success, Data = true };
            }
            catch (Exception e)
            {
                return new ResultDto<bool> { Code=Code.Failed,Data=false,Message=e.Message};
                throw;
            }
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="adminIds"></param>
        /// <returns></returns>
        public async Task<ResultDto<bool>> BatchDelAsync(List<int> adminIds)
        {
            try
            {
                await repository.DeleteAsync(adminIds);
                return new ResultDto<bool> { Code=Code.Success, Data = true };
            }
            catch (Exception e)
            {
                return new ResultDto<bool> { Code=Code.Failed,Data=false,Message=e.Message};
                throw;
            }
        }
    }
}
